package product

import (
	"context"
	"github.com/asim/go-micro/v3"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"server/proto/products"
	"server/utils"
	"strings"
	"time"
)

// GetProductList godoc
//	@Summary		获取商品列表
//	@Description	获取商品列表
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			num    formData     string  false  "num"  Format(num)
//	@Success		200		{object}  products.GetProductDetailResponse
//	@Failure		500		{object}  products.GetProductDetailResponse
//	@Router			/product/GetProducts [get]
func GetProductList(ctx *gin.Context) {
	query := ctx.Query("num")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.GetProductsList(context.TODO(), &products.GetProductsListRequest{Num: utils.StrToInt(query)})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "获取商品列表失败",
		})
		return
	}

	for i := 0; i < len(rep.Products); i++ {
		rep.Products[i].Pic = utils.ImgBase63(rep.Products[i].Pic)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":     rep.Code,
		"msg":      rep.Msg,
		"products": rep.Products,
	})
}

// GoodsDetail godoc
//	@Summary		获取商品详情
//	@Description	获取商品详情
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			id    formData     string  false  "id"  Format(id)
//	@Success		200		{object}  products.GetProductDetailResponse
//	@Failure		500		{object}  products.GetProductDetailResponse
//	@Router			/product/GoodsDetail [get]
func GoodsDetail(ctx *gin.Context) {
	//获取商品id
	query := ctx.Query("id")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.GetProductDetail(context.TODO(), &products.GetProductDetailRequest{Id: utils.StrToInt(query)})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "获取商品详情失败",
		})
		return
	}
	//将图片根据路径转化为base63
	rep.ProductPic = utils.ImgBase63(rep.ProductPic)
	ctx.JSON(http.StatusOK, gin.H{
		"code":           200,
		"msg":            "获取商品详情成功",
		"Id":             query,
		"ProductName":    rep.ProductName,
		"ProductPrice":   rep.ProductPrice,
		"ProductDesc":    rep.ProductDesc,
		"ProductAddress": rep.ProductAddress,
		"ProductNum":     rep.ProductNum,
		"ProductPic":     rep.ProductPic,
	})
}

// AddGoodsCar godoc
//	@Summary		添加购物车
//	@Description	添加购物车
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			username    formData     string  false  "username"  Format(username)
//	@Param			GoodsId    formData     string  false  "GoodsId"  Format(GoodsId)
//	@Param			GoodsNum    formData     string  false  "GoodsNum"  Format(GoodsNum)
//	@Param			Address    formData     string  false  "Address"  Format(Address)
//	@Success		200		{object}  products.AddProductGoodsCarResponse
//	@Failure		500		{object}  products.AddProductGoodsCarResponse
//	@Router			/product/AddGoodsCar [get]
func AddGoodsCar(ctx *gin.Context) {
	username := ctx.Query("username")
	GoodsId := ctx.Query("GoodsId")
	GoodsNum := ctx.Query("GoodsNum")
	Address := ctx.Query("Address")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.AddProductGoodsCar(context.TODO(), &products.AddProductGoodsCarRequest{
		Username: username,
		GoodsId:  utils.StrToInt(GoodsId),
		GoodsNum: utils.StrToInt(GoodsNum),
		Address:  Address,
	})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "加入购物车失败",
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code": rep.Code,
		"msg":  rep.Msg,
	})

}

// ShowGoodsCar godoc
//	@Summary		在展示购物车信息
//	@Description	在展示购物车信息
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			username    formData     string  false  "username"  Format(username)
//	@Success		200		{object}  products.GetProductGoodsCarResponse
//	@Failure		500		{object}  products.GetProductGoodsCarResponse
//	@Router			/product/showGoodsCar [get]
func ShowGoodsCar(ctx *gin.Context) {
	username := ctx.Query("username")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.GetProductGoodsCar(context.TODO(), &products.GetProductGoodsCarRequest{UserName: username})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "获取购物车列表失败",
		})
		return
	}

	for i := 0; i < len(rep.OrderInfo); i++ {
		rep.OrderInfo[i].ProductPic = utils.ImgBase63(rep.OrderInfo[i].ProductPic)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":  rep.Code,
		"msg":   rep.Msg,
		"Order": rep.OrderInfo,
	})
}

// DeleteGoodsCar godoc
//	@Summary		购物车删除商品
//	@Description	购物车删除商品
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			id    formData     string  false  "id"  Format(id)
//	@Success		200		{object}  products.AddProductGoodsCarResponse
//	@Failure		500		{object}  products.AddProductGoodsCarResponse
//	@Router			/product/deleteGoodsCar [post]
func DeleteGoodsCar(ctx *gin.Context) {
	id := ctx.PostForm("id")

	username := ctx.PostForm("username")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.DeleteGoodsCar(context.TODO(), &products.DeleteGoodsCarRequest{Id: utils.StrToInt(id), Username: username})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "购物车商品删除",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code": rep.Code,
		"msg":  rep.Msg,
	})

}

// BuyGoods godoc
//	@Summary		购买商品
//	@Description	购买商品
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			username    formData     string  false  "username"  Format(username)
//	@Param			GoodsId    formData     string  false  "GoodsId"  Format(GoodsId)
//	@Param			GoodsNum    formData     string  false  "GoodsNum"  Format(GoodsNum)
//	@Param			GoodsAddress    formData     string  false  "GoodsAddress"  Format(GoodsAddress)
//	@Success		200		{object}  products.AddProductGoodsCarResponse
//	@Failure		500		{object}  products.AddProductGoodsCarResponse
//	@Router			/product/BuyGoods [post]
func BuyGoods(ctx *gin.Context) {
	username := ctx.PostForm("username")
	GoodsId := ctx.PostForm("GoodsId")
	GoodsNum := ctx.PostForm("GoodsNum")
	GoodsAddress := ctx.PostForm("GoodsAddress")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.BuyGoods(context.TODO(), &products.AddProductGoodsCarRequest{
		Username: username,
		GoodsId:  utils.StrToInt(GoodsId),
		GoodsNum: utils.StrToInt(GoodsNum),
		Address:  GoodsAddress,
	})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "商品购买失败",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code": rep.Code,
		"msg":  rep.Msg,
	})
}

// BuyByCar godoc
//	@Summary		购物车购买商品
//	@Description	购物车购买商品
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			email    formData     string  false  "email"  Format(email)
//	@Param			form    formData     string  false  "form"  Format(form)
//	@Success		200		{object}  products.AddProductGoodsCarResponse
//	@Failure		500		{object}  products.AddProductGoodsCarResponse
//	@Router			/product/BuyByCar [post]
func BuyByCar(ctx *gin.Context) {
	email := ctx.PostForm("email")
	form := ctx.PostForm("All_money")
	postForm := ctx.PostForm("Goods")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	split := strings.Split(postForm, ",")

	goInt32 := utils.StrGoInt32(split)

	request := products.BuyByGoodsCarRequest{
		Email:   email,
		Account: utils.StrToInt(form),
		Goods:   goInt32,
	}

	rep, err := productsService.BuyByGoodsCar(context.TODO(), &request)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "商品购买失败",
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code": rep.Code,
		"msg":  rep.Msg,
	})
}

// GetUserOrder godoc
//	@Summary		获取用户订单
//	@Description	获取用户订单
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			email    formData     string  false  "email"  Format(email)
//	@Success		200		{object}  products.GetUserOrderResponse
//	@Failure		500		{object}  products.GetUserOrderResponse
//	@Router			/product/GetUserOrder [get]
func GetUserOrder(ctx *gin.Context) {
	email := ctx.Query("email")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.GetUserOrder(context.TODO(), &products.GetUserOrderRequest{Email: email})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "获取用户所有订单失败",
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":  rep.Code,
		"msg":   rep.Msg,
		"order": rep.Order,
	})
}

// SearchProduct godoc
//	@Summary		搜索商品
//	@Description	搜索商品
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			search    formData     string  false  "search"  Format(search)
//	@Success		200		{object}  products.GetProductsListResponse
//	@Failure		500		{object}  products.GetProductsListResponse
//	@Router			/product/searchProduct [get]
func SearchProduct(ctx *gin.Context) {
	//获取关键词
	query := ctx.Query("search")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.SearchProduct(context.TODO(), &products.SearchProductRequestIndex{Search: query})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "搜索商品错误",
		})
		return
	}

	for i := 0; i < len(rep.Products); i++ {
		rep.Products[i].Pic = utils.ImgBase63(rep.Products[i].Pic)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":    rep.Code,
		"msg":     rep.Msg,
		"product": rep.Products,
	})

}

// GetOrderList godoc
//	@Summary		获取用户订单
//	@Description	获取用户订单
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			search    formData     string  false  "search"  Format(search)
//	@Success		200		{object}  products.GetProductsListResponse
//	@Failure		500		{object}  products.GetProductsListResponse
//	@Router			/product/searchProduct [get]
func GetOrderList(ctx *gin.Context) {
	email := ctx.Query("email")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	tx, _ := context.WithTimeout(context.Background(), time.Second*5000)
	rep, err := productsService.GetOrderList(tx, &products.GetUserOrderRequest{Email: email})
	log.Println(err)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "获取用户信息失败",
		})
		return
	}
	for i := 0; i < len(rep.OrderInfo); i++ {
		rep.OrderInfo[i].ProductPic = utils.ImgBase63(rep.OrderInfo[i].ProductPic)
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code":  rep.Code,
		"msg":   rep.Msg,
		"order": rep.OrderInfo,
	})
}

// Verify godoc
//	@Summary		进行hash验证
//	@Description	进行hash验证
//	@Tags			商品模块
//	@Accept			json
//	@Produce		json
//	@Param			url    formData     string  false  "url"  Format(url)
//	@Success		200		{object}  products.GetProductsListResponse
//	@Failure		500		{object}  products.GetProductsListResponse
//	@Router			/product/searchProduct [get]
func Verify(ctx *gin.Context) {
	//解析参数 获取hash值
	hash, _ := ctx.GetQuery("hash")

	service := micro.NewService()

	productsService := products.NewProductsService("develop_product", service.Client())

	rep, err := productsService.VerifyHash(context.TODO(), &products.VerifyHashRequest{BlockHash: hash})
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": 500,
			"msg":  "获取数据失败",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code": rep.Code,
		"msg":  rep.Msg,
		"url":  rep.TransactionsHash,
	})
}
